home *** CD-ROM | disk | FTP | other *** search
/ Mac Power 1997 December / MACPOWER-1997-12.ISO.7z / MACPOWER-1997-12.ISO / AMUG / PROGRAMMING / Raven 1.2.sit / Raven 1.2 / • Extras • / SGI STL / function.h < prev    next >
C/C++ Source or Header  |  1997-06-22  |  18KB  |  577 lines

  1. /*
  2.  *
  3.  * Copyright (c) 1994
  4.  * Hewlett-Packard Company
  5.  *
  6.  * Permission to use, copy, modify, distribute and sell this software
  7.  * and its documentation for any purpose is hereby granted without fee,
  8.  * provided that the above copyright notice appear in all copies and
  9.  * that both that copyright notice and this permission notice appear
  10.  * in supporting documentation.  Hewlett-Packard Company makes no
  11.  * representations about the suitability of this software for any
  12.  * purpose.  It is provided "as is" without express or implied warranty.
  13.  *
  14.  *
  15.  * Copyright (c) 1996
  16.  * Silicon Graphics Computer Systems, Inc.
  17.  *
  18.  * Permission to use, copy, modify, distribute and sell this software
  19.  * and its documentation for any purpose is hereby granted without fee,
  20.  * provided that the above copyright notice appear in all copies and
  21.  * that both that copyright notice and this permission notice appear
  22.  * in supporting documentation.  Silicon Graphics makes no
  23.  * representations about the suitability of this software for any
  24.  * purpose.  It is provided "as is" without express or implied warranty.
  25.  *
  26.  * Copyright (c) 1997
  27.  * Moscow Center for SPARC Technology
  28.  *
  29.  * Permission to use, copy, modify, distribute and sell this software
  30.  * and its documentation for any purpose is hereby granted without fee,
  31.  * provided that the above copyright notice appear in all copies and
  32.  * that both that copyright notice and this permission notice appear
  33.  * in supporting documentation.  Moscow Center for SPARC Technology makes no
  34.  * representations about the suitability of this software for any
  35.  * purpose.  It is provided "as is" without express or implied warranty.
  36.  *
  37.  */
  38.  
  39. #ifndef __SGI_STL_FUNCTION_H
  40. #define __SGI_STL_FUNCTION_H
  41.  
  42. #include <stddef.h>
  43. # ifndef __SGI_STL_BOOL_H
  44. #  include <bool.h>
  45. # endif
  46.  
  47. __BEGIN_STL_NAMESPACE
  48.  
  49. template <class T>
  50. inline bool operator!=(const T& x, const T& y) {
  51.     return !(x == y);
  52. }
  53.  
  54. template <class T>
  55. inline bool operator>(const T& x, const T& y) {
  56.     return y < x;
  57. }
  58.  
  59. template <class T>
  60. inline bool operator<=(const T& x, const T& y) {
  61.     return !(y < x);
  62. }
  63.  
  64. template <class T>
  65. inline bool operator>=(const T& x, const T& y) {
  66.     return !(x < y);
  67. }
  68.  
  69. template <class Arg, class Result>
  70. struct unary_function {
  71.     typedef Arg argument_type;
  72.     typedef Result result_type;
  73. };
  74.  
  75. template <class Arg1, class Arg2, class Result>
  76. struct binary_function {
  77.     typedef Arg1 first_argument_type;
  78.     typedef Arg2 second_argument_type;
  79.     typedef Result result_type;
  80. };      
  81.  
  82. template <class T>
  83. struct plus : public binary_function<T, T, T> {
  84.     T operator()(const T& x, const T& y) const { return x + y; }
  85. };
  86.  
  87. template <class T>
  88. struct minus : public binary_function<T, T, T> {
  89.     T operator()(const T& x, const T& y) const { return x - y; }
  90. };
  91.  
  92. template <class T>
  93. struct multiplies : public binary_function<T, T, T> {
  94.     T operator()(const T& x, const T& y) const { return x * y; }
  95. };
  96.  
  97. template <class T>
  98. struct divides : public binary_function<T, T, T> {
  99.     T operator()(const T& x, const T& y) const { return x / y; }
  100. };
  101.  
  102. template <class T>
  103. struct modulus : public binary_function<T, T, T> {
  104.     T operator()(const T& x, const T& y) const { return x % y; }
  105. };
  106.  
  107. template <class T>
  108. struct negate : public unary_function<T, T> {
  109.     T operator()(const T& x) const { return -x; }
  110. };
  111.  
  112. template <class T>
  113. struct equal_to : public binary_function<T, T, bool> {
  114.     bool operator()(const T& x, const T& y) const { return x == y; }
  115. };
  116.  
  117. template <class T>
  118. struct not_equal_to : public binary_function<T, T, bool> {
  119.     bool operator()(const T& x, const T& y) const { return x != y; }
  120. };
  121.  
  122. template <class T>
  123. struct greater : public binary_function<T, T, bool> {
  124.     bool operator()(const T& x, const T& y) const { return x > y; }
  125. };
  126.  
  127. template <class T>
  128. struct less : public binary_function<T, T, bool> {
  129.     bool operator()(const T& x, const T& y) const { return x < y; }
  130. };
  131.  
  132. template <class T>
  133. struct greater_equal : public binary_function<T, T, bool> {
  134.     bool operator()(const T& x, const T& y) const { return x >= y; }
  135. };
  136.  
  137. template <class T>
  138. struct less_equal : public binary_function<T, T, bool> {
  139.     bool operator()(const T& x, const T& y) const { return x <= y; }
  140. };
  141.  
  142. template <class T>
  143. struct logical_and : public binary_function<T, T, bool> {
  144.     bool operator()(const T& x, const T& y) const { return x && y; }
  145. };
  146.  
  147. template <class T>
  148. struct logical_or : public binary_function<T, T, bool> {
  149.     bool operator()(const T& x, const T& y) const { return x || y; }
  150. };
  151.  
  152. template <class T>
  153. struct logical_not : public unary_function<T, bool> {
  154.     bool operator()(const T& x) const { return !x; }
  155. };
  156.  
  157. #  if defined (__STL_BASE_TYPEDEF_BUG)
  158. // this workaround is needed for SunPro 4.0.1
  159. // suggested by "Martin Abernethy" <gma@paston.co.uk>:
  160.  
  161. // We have to introduce the XXary_predicate_aux structures in order to
  162. // access the argument and return types of predicate functions supplied
  163. // as type parameters. SUN C++ 4.0.1 compiler gives errors for template type parameters
  164. // of the form 'name1::name2', where name1 is itself a type parameter.
  165.  
  166. template <class Operation>
  167. struct __unary_fun_aux : private Operation
  168. {
  169.     typedef typename Operation::argument_type argument_type;
  170.     typedef typename Operation::result_type result_type;
  171. };
  172.  
  173. template <class Operation>
  174. struct __binary_fun_aux : private Operation
  175. {
  176.     typedef typename Operation::first_argument_type first_argument_type;
  177.     typedef typename Operation::second_argument_type second_argument_type;
  178.     typedef typename Operation::result_type result_type;
  179. };
  180.  
  181. #  define __UNARY_ARG(Operation,type)  __unary_fun_aux<Operation>::type
  182. #  define __BINARY_ARG(Operation,type)  __binary_fun_aux<Operation>::type
  183. # else
  184. #  define __UNARY_ARG(Operation,type)  Operation::type
  185. #  define __BINARY_ARG(Operation,type) Operation::type
  186. # endif
  187.  
  188. template <class Predicate>
  189. class unary_negate : 
  190.     public unary_function<typename __UNARY_ARG(Predicate,argument_type), bool> {
  191. protected:
  192.     Predicate pred;
  193. public:
  194.     
  195.     explicit unary_negate(const Predicate& x) : pred(x) {}
  196.     bool operator()(const argument_type& x) const { return !pred(x); }
  197. };
  198.  
  199. template <class Predicate>
  200. inline unary_negate<Predicate> not1(const Predicate& pred) {
  201.   return unary_negate<Predicate>(pred);
  202. }
  203.  
  204. template <class Predicate> 
  205. class binary_negate 
  206.     : public binary_function<typename __BINARY_ARG(Predicate,first_argument_type),
  207.                  typename __BINARY_ARG(Predicate,second_argument_type), 
  208.                              bool> {
  209. protected:
  210.     Predicate pred;
  211. public:
  212.     explicit binary_negate(const Predicate& x) : pred(x) {}
  213.     bool operator()(const first_argument_type& x, 
  214.             const second_argument_type& y) const {
  215.     return !pred(x, y); 
  216.     }
  217. };
  218.  
  219. template <class Predicate>
  220. inline binary_negate<Predicate> not2(const Predicate& pred) {
  221.   return binary_negate<Predicate>(pred);
  222. }
  223.  
  224. template <class Operation> 
  225. class binder1st : 
  226.     public unary_function<typename __BINARY_ARG(Operation,second_argument_type),
  227.                           typename __BINARY_ARG(Operation,result_type) > {
  228. protected:
  229.     Operation op;
  230.     typename __BINARY_ARG(Operation,first_argument_type) value;
  231. public:
  232.     binder1st(const Operation& x, 
  233.               const typename __BINARY_ARG(Operation,first_argument_type)& y)
  234.     : op(x), value(y) {}
  235.     result_type operator()(const argument_type& x) const {
  236.     return op(value, x); 
  237.     }
  238. };
  239.  
  240. template <class Operation, class T>
  241. binder1st<Operation> bind1st(const Operation& op, const T& x) {
  242.     typedef typename __BINARY_ARG(Operation,first_argument_type) arg_type;
  243.     return binder1st<Operation>(op, arg_type(x));
  244. }
  245.  
  246. template <class Operation> 
  247. class binder2nd : 
  248.     public unary_function<typename __BINARY_ARG(Operation,first_argument_type),
  249.                           typename __BINARY_ARG(Operation,result_type)> {
  250. protected:
  251.     Operation op;
  252.     typename __BINARY_ARG(Operation,second_argument_type) value;
  253. public:
  254.     binder2nd(const Operation& x, 
  255.               const typename __BINARY_ARG(Operation,second_argument_type)& y) 
  256.     : op(x), value(y) {}
  257.     result_type operator()(const argument_type& x) const {
  258.     return op(x, value); 
  259.     }
  260. };
  261.  
  262. template <class Operation, class T>
  263. binder2nd<Operation> bind2nd(const Operation& op, const T& x) {
  264.     typedef typename __BINARY_ARG(Operation,second_argument_type) arg_type;
  265.     return binder2nd<Operation>(op, arg_type(x));
  266. }
  267.  
  268. template <class Operation1, class Operation2>
  269. class unary_compose : 
  270.     public unary_function<typename __UNARY_ARG(Operation2,argument_type),
  271.                           typename __UNARY_ARG(Operation1,result_type)> {
  272. protected:
  273.     Operation1 op1;
  274.     Operation2 op2;
  275. public:
  276.     unary_compose(const Operation1& x, const Operation2& y) : op1(x), op2(y) {}
  277.     typename __UNARY_ARG(Operation1,result_type) 
  278.     operator()(const typename __UNARY_ARG(Operation2,argument_type)& x) const {
  279.     return op1(op2(x));
  280.     }
  281. };
  282.  
  283. template <class Operation1, class Operation2>
  284. inline unary_compose<Operation1, Operation2> compose1(const Operation1& op1, 
  285.                                                       const Operation2& op2) {
  286.   return unary_compose<Operation1, Operation2>(op1, op2);
  287. }
  288.  
  289. template <class Operation1, class Operation2, class Operation3>
  290. class binary_compose : 
  291.     public unary_function<typename __UNARY_ARG(Operation2,argument_type),
  292.                           typename __BINARY_ARG(Operation1,result_type)> {
  293. protected:
  294.     Operation1 op1;
  295.     Operation2 op2;
  296.     Operation3 op3;
  297. public:
  298.     binary_compose(const Operation1& x, const Operation2& y, 
  299.            const Operation3& z) : op1(x), op2(y), op3(z) { }
  300.     typename __BINARY_ARG(Operation1,result_type) 
  301.     operator()(const typename __UNARY_ARG(Operation2,argument_type)& x) const {
  302.     return op1(op2(x), op3(x));
  303.     }
  304. };
  305.  
  306. template <class Operation1, class Operation2, class Operation3>
  307. inline binary_compose<Operation1, Operation2, Operation3> 
  308. compose2(const Operation1& op1, const Operation2& op2, const Operation3& op3) {
  309.   return binary_compose<Operation1, Operation2, Operation3>(op1, op2, op3);
  310. }
  311.  
  312. template <class Arg, class Result>
  313. class pointer_to_unary_function : public unary_function<Arg, Result> {
  314. protected:
  315.     Result (*ptr)(Arg);
  316. public:
  317.     pointer_to_unary_function() {}
  318.     explicit pointer_to_unary_function(Result (*x)(Arg)) : ptr(x) {}
  319.     Result operator()(Arg x) const { return ptr(x); }
  320. };
  321.  
  322. template <class Arg, class Result>
  323. inline pointer_to_unary_function<Arg, Result> ptr_fun(Result (*x)(Arg)) {
  324.   return pointer_to_unary_function<Arg, Result>(x);
  325. }
  326.  
  327. template <class Arg1, class Arg2, class Result>
  328. class pointer_to_binary_function : public binary_function<Arg1, Arg2, Result> {
  329. protected:
  330.     Result (*ptr)(Arg1, Arg2);
  331. public:
  332.     pointer_to_binary_function() {}
  333.     explicit pointer_to_binary_function(Result (*x)(Arg1, Arg2)) : ptr(x) {}
  334.     Result operator()(Arg1 x, Arg2 y) const { return ptr(x, y); }
  335. };
  336.  
  337. template <class Arg1, class Arg2, class Result>
  338. inline pointer_to_binary_function<Arg1, Arg2, Result> 
  339. ptr_fun(Result (*x)(Arg1, Arg2)) {
  340.     return pointer_to_binary_function<Arg1, Arg2, Result>(x);
  341. }
  342.  
  343. template <class T>
  344. struct identity : public unary_function<T, T> {
  345.     const T& operator()(const T& x) const { return x; }
  346. };
  347.  
  348. #if 1
  349. template <class T, class U>        // ・・・ハJDJ (CW Pro1 doesn't like const when first_type is also const)
  350. struct select1st : public unary_function<T, U> {
  351.     const U& operator () (const T& x) const { return x.first; }
  352. };
  353. #else
  354. template <class Pair>
  355. struct select1st : public unary_function<Pair, typename Pair::first_type> {
  356.   const typename Pair::first_type& operator()(const Pair& x) const
  357.   {
  358.     return x.first;
  359.   }
  360. };
  361. #endif
  362.  
  363. template <class Pair>
  364. struct select2nd : public unary_function<Pair, typename Pair::second_type> {
  365.   const typename Pair::second_type& operator()(const Pair& x) const
  366.   {
  367.     return x.second;
  368.   }
  369. };
  370.  
  371. template <class Arg1, class Arg2>
  372. struct project1st : public binary_function<Arg1, Arg2, Arg1> {
  373.   Arg1 operator()(const Arg1& x, const Arg2&) const { return x; }
  374. };
  375.  
  376. template <class Arg1, class Arg2>
  377. struct project2nd : public binary_function<Arg1, Arg2, Arg2> {
  378.   Arg2 operator()(const Arg1&, const Arg2& y) const { return y; }
  379. };
  380.  
  381. //  SGI extension (constant functions)
  382.  
  383. template <class Result>
  384. struct constant_void_fun
  385. {
  386.   typedef Result result_type;
  387.   result_type val;
  388.   constant_void_fun(const result_type& v) : val(v) {}
  389.   const result_type& operator()() const { return val; }
  390. };  
  391.  
  392. template <class Result, __DFL_TMPL_PARAM(Argument, Result) >
  393. struct constant_unary_fun : public unary_function<Argument, Result> {
  394. # if defined (__STL_BASE_TYPEDEF_BUG)
  395.   typedef unary_function<Argument, Result> super;
  396.   typedef super::result_type result_type;
  397.   typedef super::argument_type argument_type;
  398. #  endif
  399.   result_type val;
  400.   constant_unary_fun(const result_type& v) : val(v) {}
  401.   const result_type& operator()(const argument_type&) const { return val; }
  402. };
  403.  
  404. template <class Result, __DFL_TMPL_PARAM(Arg1,Result), 
  405.     __DFL_TMPL_PARAM(Arg2,Arg1) >
  406. struct constant_binary_fun : public binary_function<Arg1, Arg2, Result> {
  407. # if defined (__STL_BASE_TYPEDEF_BUG)
  408.   typedef binary_function<Arg1, Arg2, Result> super;
  409.   typedef super::result_type result_type;
  410.   typedef super::first_argument_type first_argument_type;
  411.   typedef super::second_argument_type second_argument_type;
  412. #  endif
  413.   result_type val;
  414.   constant_binary_fun(const result_type& v) : val(v) {}
  415.   const result_type& operator()(const first_argument_type&, 
  416.                                 const second_argument_type&) const {
  417.     return val;
  418.   }
  419. };
  420.  
  421. template <class Result>
  422. inline constant_void_fun<Result> constant0(const Result& val)
  423. {
  424.   return constant_void_fun<Result>(val);
  425. }
  426.  
  427. template <class Result>
  428. inline constant_unary_fun<Result __DFL_TMPL_ARG(Result) > constant1(const Result& val)
  429. {
  430.   return constant_unary_fun<Result, Result>(val);
  431. }
  432.  
  433. template <class Result>
  434. inline constant_binary_fun<Result 
  435.   __DFL_TMPL_ARG(Result) __DFL_TMPL_ARG(Result) > constant2(const Result& val)
  436. {
  437.   return constant_binary_fun<Result __DFL_TMPL_ARG(Result) __DFL_TMPL_ARG(Result)  >(val);
  438. }
  439.  
  440. //  SGI extension (subtractive range)
  441.  
  442. // Note: this code assumes that T is 32-bit unsigned integer.
  443. template < class T >
  444. class __subtractive_rng_t : public unary_function<T, T> {
  445. private:
  446.   T table[55];
  447.   size_t index1;
  448.   size_t index2;
  449. public:
  450.   __subtractive_rng_t(T seed) { initialize(seed); }
  451.   __subtractive_rng_t() { initialize(161803398u); }
  452.  
  453.   T operator()(T limit) {
  454.     index1 = (index1 + 1) % 55;
  455.     index2 = (index2 + 1) % 55;
  456.     table[index1] = table[index1] - table[index2];
  457.     return table[index1] % limit;
  458.   }
  459.   void initialize(T seed);
  460. };
  461.  
  462. template <class T>
  463. void __subtractive_rng_t<T>::initialize(T seed) {
  464.     T k = 1;
  465.     table[54] = seed;
  466.     size_t i;
  467.     for (i = 0; i < 54; i++) {
  468.         size_t ii = (21 * (i + 1) % 55) - 1;
  469.         table[ii] = k;
  470.         k = seed - k;
  471.         seed = table[ii];
  472.     }
  473.     for (int loop = 0; loop < 4; loop++) {
  474.         for (i = 0; i < 55; i++)
  475.             table[i] = table[i] - table[(1 + i + 30) % 55];
  476.     }
  477.     index1 = 0;
  478.     index2 = 31;
  479.   }
  480.  
  481. typedef __subtractive_rng_t<__STL_UINT32_T> subtractive_rng;
  482.  
  483.  
  484. // 20.3.8  Adaptors for pointers to members [lib.member.pointer.adaptors]       
  485.  
  486. // mem_fun_t calls the member function it is  initialized  with  given  a
  487. // pointer argument.
  488. template <class Class, class Result> 
  489. class mem_fun_t : public unary_function<Class*, Result> {
  490. protected:
  491.     typedef Result (Class::*fun_type)(void);
  492.     fun_type ptr;
  493. public:
  494.     mem_fun_t() {}
  495.     explicit mem_fun_t(fun_type p) : ptr(p) {}
  496.     Result operator()(Class* x) const { return (x->*ptr)();}
  497. };
  498.  
  499. //   mem_fun1_t  calls  the  member function it is initialized with given a
  500. //   pointer argument and an additional argument of the appropriate type.
  501. template <class Class, class Arg, class Result>
  502. class mem_fun1_t: public binary_function<Class*, Arg, Result> {
  503. public:
  504. protected:
  505.     typedef Result (Class::*fun_type)(Arg);
  506.     fun_type ptr;
  507. public:
  508.     mem_fun1_t() {}
  509.     explicit mem_fun1_t(fun_type p) : ptr(p) {}
  510.     Result operator()(Class* x, Arg a) const { return (x->*ptr)(a);}
  511. };
  512.  
  513. // mem_fun_ref_t calls the member function it is initialized with given a
  514. // reference argument.
  515. template <class Class, class Result> 
  516. class mem_fun_ref_t : public unary_function<Class, Result> {
  517. protected:
  518.     typedef Result (Class::*fun_type)(void);
  519.     fun_type ptr;
  520. public:
  521.     mem_fun_ref_t() {}
  522.     explicit mem_fun_ref_t(fun_type p) : ptr(p) {}
  523.     Result operator()(Class& x) const { return (x.*ptr)();}
  524. };
  525.  
  526. // mem_fun1_ref_t  calls the member function it is initialized with given
  527. // a reference argument and an additional  argument  of  the  appropriate
  528. // type.
  529. template <class Class, class Arg, class Result>
  530. class mem_fun1_ref_t: public binary_function<Class, Arg, Result> {
  531. public:
  532. protected:
  533.     typedef Result (Class::*fun_type)(Arg);
  534.     fun_type ptr;
  535. public:
  536.     mem_fun1_ref_t() {}
  537.     explicit mem_fun1_ref_t(fun_type p) : ptr(p) {}
  538.     Result operator()(Class& x, Arg a) const { return (x.*ptr)(a);}
  539. };
  540.  
  541. # if !defined (__STL_MEMBER_POINTER_PARAM_BUG)
  542. //  mem_fun(&X::f) returns an object through  which  X::f  can  be  called
  543. //  given  a  pointer  to an X followed by the argument required for f (if
  544. //  any).
  545. template <class Class, class Result>
  546. inline mem_fun_t <Class, Result> 
  547. mem_fun(Result (Class::*ptr)(void)) {
  548.     return mem_fun_t<Class, Result>(ptr);
  549. }
  550.  
  551. template <class Class, class Arg, class Result>
  552. inline mem_fun1_t <Class, Arg, Result> 
  553. mem_fun1(Result (Class::*ptr)(Arg)) {
  554.     return mem_fun1_t<Class, Arg, Result>(ptr);
  555. }
  556.  
  557. //  mem_fun_ref(&X::f)  returns an object through which X::f can be called
  558. //  given a reference to an X followed by the argument required for f  (if
  559. //  any).
  560. template <class Class, class Result>
  561. inline mem_fun_ref_t<Class, Result> 
  562. mem_fun_ref(Result (Class::*ptr)(void)) {
  563.     return mem_fun_ref_t<Class, Result>(ptr);
  564. }
  565.  
  566. template <class Class, class Arg, class Result>
  567. inline mem_fun1_ref_t<Class, Arg, Result> 
  568. mem_fun1_ref(Result (Class::*ptr)(Arg)) {
  569.     return mem_fun1_ref_t<Class, Arg, Result>(ptr);
  570. }
  571.  
  572. # endif
  573.  
  574. __END_STL_NAMESPACE
  575.  
  576. #endif
  577.